<template>
  <el-form ref="form" :model="spuInfo" label-width="100px" v-show="visible">
    <!-- SPU名称 -->
    <el-form-item label="SPU名称">
      <el-input v-model="spuInfo.spuName" placeholder="请输入SPU名称"></el-input>
    </el-form-item>
    <!-- spu品牌 -->
    <el-form-item label="SPU品牌">
      <el-select v-model="spuInfo.tmId" placeholder="请选择品牌">
        <el-option v-for="item in trademarkList" :label="item.tmName" :value="item.id" :key="item.id"></el-option>
      </el-select>
    </el-form-item>
    <!-- spu描述 -->
    <el-form-item label="SPU描述">
      <el-input type="textarea" rows="4" v-model="spuInfo.description" placeholder="请输入SPU描述信息"></el-input>
    </el-form-item>
    <!-- SPU图片 -->
    <el-form-item label="SPU图片">
      <el-upload action="dev-api/admin/product/fileUpload" list-type="picture-card"
        :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handleAvatarSuccess"
        :before-upload="beforeAvatarUpload" :file-list="spuImageList" multiple>
        <i class="el-icon-plus"></i>
      </el-upload>
      <el-dialog :visible.sync="dialogVisible">
        <img width="100%" :src="dialogImageUrl" alt="">
      </el-dialog>
    </el-form-item>
    <!-- 销售属性 -->
    <el-form-item label="销售属性">
      <el-select v-model="attrIdAttrName"
        :placeholder="`${unSelectedSaleAttrList.length>0?`还有${unSelectedSaleAttrList.length}个未选择`:'没有了'}`">
        <el-option v-for="attr in unSelectedSaleAttrList" :key="attr.id" :label="attr.name"
          :value="attr.id+':'+attr.name">
        </el-option>
      </el-select>
      <el-button type="primary" icon="el-icon-plus" @click="addAttr" :disabled='!attrIdAttrName'>添加销售属性</el-button>
    </el-form-item>
    <!-- 表格 -->
    <el-form-item>
      <el-table :data="spuInfo.spuSaleAttrList" style="width: 100%">
        <el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
        <el-table-column label="属性名" width="150" prop="saleAttrName"></el-table-column>
        <el-table-column label="属性值名称列表">
          <template slot-scope="{row, $index}">
            <el-tag :key="attr.id" v-for="(attr, index) in row.spuSaleAttrValueList" closable
              :disable-transitions="false" @close="handleClose(row.spuSaleAttrValueList,index)">
              {{attr.saleAttrValueName}}
            </el-tag>
            <el-input class="input-new-tag" v-if="row.edit" v-model="row.saleAttrValueName" ref="saveTagInput"
              size="small" @keyup.enter.native="handleInputConfirm(row)" @blur="handleInputConfirm(row)">
            </el-input>
            <el-button v-else class="button-new-tag" size="small" @click="showInput(row)">+ 添加</el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150">
          <template slot-scope="{row,$index}">
            <el-popconfirm :title="`您确定要删除吗?`" @onConfirm='deleteVal($index)'>
              <HintButton title="删除属性值" size="mini" type="danger" icon="el-icon-delete" slot="reference" />
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <!-- 两个按钮 -->
    <el-form-item>
      <el-button type="primary" @click="save">保存</el-button>
      <el-button @click="back">返回</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
  export default {
    name: 'spuForm',
    props: ['visible'],
    data() {
      return {
        spuInfo: {
          spuName: '', //spuinfo对象的名字
          description: '', // spuinfo对象的描述信息
          category3Id: '', //三级分类的id
          tmId: '', //品牌的id
          spuSaleAttrList: [], //spuinfo对象中的销售属性数组数据
          spuImageList: [] //图片列表数据
        },
        dialogImageUrl: '',
        dialogVisible: false,
        trademarkList: [], // 所有的品牌列表数据
        saleAttrList: [], // 所有的销售属性数据
        spuImageList: [], // 所有的图片列表数据
        attrIdAttrName: '', // 用来存储选中的销售属性的id和名字的
      }
    },
    methods: {
      //回退操作
      back() {
        this.$emit('update:visible', false);
      },
      //修改spuInfo对象的初始化的相关方法
      initUpdateData(spuId) {
        this.spuId = spuId;

        this.getSpuImageList(); //根据spuId获取对应的spuInfo对象的图片列表数据
        this.getBaseSaleAttrList(); //获取所有的销售属性
        this.getTrademarkList(); //获取品牌数据
        this.getSpuInfoById(); //根据spuId获取对应的spuInfo对象数据
      },
      //删掉图片的回调
      handleRemove(file, fileList) {
        this.spuImageList = fileList; // fileList是移除图片后的数组
      },
      //预览图片的回调
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url; //设置预览图片的地址
        this.dialogVisible = true; // 是否开启预览的效果
      },
      //图片上传成功的回调
      handleAvatarSuccess(res, file, fileList) {
        this.spuImageList = fileList;
      },
      //图片的验证
      beforeAvatarUpload(file) {
        const isJPG = ['image/jpeg', 'image/png'].includes(file.type);
        const isLt2M = file.size / 1024 / 1024 < 2;
        //限制图片的格式
        if (!isJPG) {
          this.$message.error('上传头像图片只能是 JPG 格式!');
        }
        //限制图片的大小
        if (!isLt2M) {
          this.$message.error('上传头像图片大小不能超过 2MB!');
        }
        return isJPG && isLt2M;
      },
      //根据spuId获取对应的spuInfo对象的图片列表数据
      async getSpuImageList() {
        const result = await this.$API.sku.getSpuImageList(this.spuId); //获取图片数组
        if (result.code !== 200) return;
        const spuImageList = result.data
        // 由于图片组件中用的属性是name和url,故新添加属性
        spuImageList.forEach(item => {
          item.name = item.imgName;
          item.url = item.imgUrl
        });
        this.spuImageList = spuImageList
      },
      //获取所有的销售属性
      async getBaseSaleAttrList() {
        const result = await this.$API.spu.getBaseSaleAttrList();
        this.saleAttrList = result.data;
      },
      //获取品牌数据
      async getTrademarkList() {
        const result = await this.$API.trademark.getTrademarkList();
        if (result.code !== 200) return;
        this.trademarkList = result.data;
      },
      //根据spuId获取对应的spuInfo对象数据
      async getSpuInfoById() {
        const result = await this.$API.spu.getSpuInfoById(this.spuId);
        if (result.code !== 200) return;
        this.spuInfo = result.data;
      },
      //删除某个属性的操作
      deleteVal(index) {
        this.spuInfo.spuSaleAttrList.splice(index, 1);
      },
      //操作销售属性值
      handleClose(tagList, index) {
        tagList.splice(index, 1);
      },
      // 展示输入框
      showInput(attr) {
        console.log(attr);
        // 判断点击的元素是否有edit属性
        if (!attr.hasOwnProperty('edit')) {
          this.$set(attr, 'edit', true); // 添加响应式属性
        } else {
          attr.edit = true;
        }
        this.$nextTick(() => {
          this.$refs.saveTagInput.focus(); // 获取焦点
        })
      },
      //查看模式，文本框输入内容后，要进行属性值添加的操作
      handleInputConfirm(attr) {
        const saleAttrValueName = attr.saleAttrValueName; // 取出添加的名字
        // 判断其是否有值或者是否是空串,空串关闭输入框且不添加内容
        if (!saleAttrValueName || !saleAttrValueName.trim()) {
          attr.edit = false;
          return;
        }
        // 计算是否重复
        const isRepeat = attr.spuSaleAttrValueList.some(item => item.saleAttrValueName === saleAttrValueName.trim());

        if (!isRepeat) {
          attr.spuSaleAttrValueList.push({
            baseSaleAttrId: attr.baseSaleAttrId,
            saleAttrValueName
          })
        } else {
          this.$message.warning('您输入了重复的数据,请重新输入');
        }
        attr.edit = false;
        attr.saleAttrValueName = ''; // 重置输入内容
      },
      //添加销售属性
      addAttr() {
        const [baseSaleAttrId, saleAttrName] = this.attrIdAttrName.split(':'); //获取选中的销售属性数据中的id和名字
        //向销售属性数组中添加数据
        this.spuInfo.spuSaleAttrList.push({
          baseSaleAttrId,
          saleAttrName,
          spuSaleAttrValueList: []
        });
        this.attrIdAttrName = ''; //清空数据的操作
      },
      //保存操作
      async save() {
        const {
          spuInfo,
          spuImageList
        } = this;
        // 对图片数组进行处理,保留两个属性
        spuInfo.spuImageList = spuImageList.map(item => ({
          imgName: item.name,
          imgUrl: item.response ? item.response.data : item.imgUrl
        }));
        // 对销售属性数组进行处理,删除掉不必要的属性
        spuInfo.spuSaleAttrList = spuInfo.spuSaleAttrList.filter(item => {
          if (item.spuSaleAttrValueList.length > 0) {
            delete item.edit;
            delete item.saleAttrValueName;
            return true;
          }
          return false;
        });

        try {
          await this.$API.spu.addOrUpdateSpuInfo(spuInfo); //提交修改
          this.$message.success('操作成功');
          this.back(); // 返回展示页面
          this.resetData(); // 重置数据
          this.$emit('saveSuccess');
        } catch (error) {
          this.$message.error(error.message || '操作失败');
        }
      },
      //重置数据
      resetData() {
        this.spuInfo = {
            spuName: '', //spuinfo对象的名字
            description: '', // spuinfo对象的描述信息
            category3Id: '', //三级分类的id
            tmId: '', //品牌的id
            spuSaleAttrList: [], //spuinfo对象中的销售属性数组数据
            spuImageList: [] //图片列表数据
          },
          this.dialogImageUrl = '';
        this.dialogVisible = false;
        this.trademarkList = []; // 所有的品牌列表数据
        this.saleAttrList = []; // 所有的销售属性数据
        this.spuImageList = []; // 所有的图片列表数据
        this.attrIdAttrName = ''; // 用来存储选中的销售属性的id和名字的
      },
      //添加spuInfo对象所需要的数据
      initAddData(category3Id) {
        this.spuInfo.category3Id = category3Id;
        this.getTrademarkList(); // 获取品牌信息数据
        this.getBaseSaleAttrList(); // 获取销售属性数据
      }
    },
    computed: {
      unSelectedSaleAttrList() {
        //解构出所有的销售属性数组和spuInfo对象中的销售属性数组
        const {
          saleAttrList,
          spuInfo: {
            spuSaleAttrList
          }
        } = this;
        //进行数据过滤,留下的数组会返回到unSelectedSaleAttrList数组中(没有选中的数据)
        return saleAttrList.filter(saleAttr => !spuSaleAttrList.some(spuSaleAttr => spuSaleAttr.saleAttrName == saleAttr
          .name))
      }
    }
  }

</script>

<style>
  .el-tag+.el-tag {
    margin-left: 10px;
  }

  .button-new-tag {
    margin-left: 10px;
    height: 32px;
    line-height: 30px;
    padding-top: 0;
    padding-bottom: 0;
  }

  .input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
  }

</style>
